﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Library.WebControls.SimpleGridView;

namespace Library.WebControls.SimpleCombobox {
	[ToolboxBitmap(typeof(SpCombobox), "Library.WebControls.SimpleCombobox.SpCombobox.bmp")]
	[SupportsEventValidation]
	[ParseChildren(true)]
	[PersistChildren(false)]

	[ToolboxData("<{0}:SpExCombobox runat=server></{0}:SpExCombobox>")]

	[DesignTimeVisible(true)]
	public class SpExCombobox : BaseAjaxControl, IEffectControl, IPagingControl {

		public SpExCombobox() {
			ClientScript = new ExClientScript();
			CloseMode = MenuContainerMode.ButtonOnly;
			ShowKey = SpShowKey.None;
		}
		[DefaultValue("~/style/simple/spexcbx-ui.css")]
		public override string CssFileName {
			get {
				return base.CssFileName;
			}
			set {
				base.CssFileName = value;
			}
		}
		[DefaultValue(PagingType.Automatic)]
		public PagingType PagingType {
			get {
				EnsureChildControls();
				return _gridView.PagingType;
			}
			set {
				EnsureChildControls();
				_gridView.PagingType = value;
			}
		}
		public object DataSource {
			get {
				EnsureChildControls();
				return _gridView.DataSource;
			}
			set {
				EnsureChildControls();
				_gridView.DataSource = value;
			}
		}
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[MergableProperty(false)]
		[Category("Data")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[DefaultValue("")]
		public ExClientScript ClientScript {
			private set;
			get;
		}
		public string TextField { get; set; }

		public string ValueField {
			get {
				EnsureChildControls();
				return _gridView.KeyFieldName;
			}
			set {
				EnsureChildControls();
				_gridView.KeyFieldName = value;
			}
		}
		[DefaultValue(typeof(Unit), "")]
		public Unit Height {
			get {
				EnsureChildControls();
				return new Unit(_divContextMenu.Style[HtmlTextWriterStyle.Height]);
			}
			set {
				EnsureChildControls();
				_divContextMenu.Style[HtmlTextWriterStyle.Height] = value.ToString();
			}
		}
		[DefaultValue(typeof(Unit), "")]
		public Unit Width {
			get {
				EnsureChildControls();
				return new Unit(_divTextButtonBox.Style[HtmlTextWriterStyle.Width]);
			}
			set {
				EnsureChildControls();
				_divTextButtonBox.Style[HtmlTextWriterStyle.Width] = value.ToString();
				//if (value.Type != UnitType.Percentage)
				//  _divContextMenu.Style[HtmlTextWriterStyle.Width] = value.ToString();
				//_textCombobox.Width = new Unit(value.Value - _image.Width.Value - 2);
			}
		}
		[DefaultValue("")]
		public Unit ContextMenuWidth {
			get {
				EnsureChildControls();
				return new Unit(_divContextMenu.Style[HtmlTextWriterStyle.Width]);
			}
			set {
				EnsureChildControls();

				if (value.Type != UnitType.Percentage)
					_divContextMenu.Style[HtmlTextWriterStyle.Width] = value.ToString();

			}
		}
		[DefaultValue(0)]
		public int TotalItems {
			get {
				EnsureChildControls();
				return _gridView.TotalItems;
			}
			set {
				EnsureChildControls();
				_gridView.TotalItems = value;
			}
		}
		[DefaultValue(1)]
		public int PageIndex {
			get {
				EnsureChildControls();
				return _gridView.PageIndex;
			}
			set {
				EnsureChildControls();
				_gridView.PageIndex = value;
			}
		}
		[DefaultValue(10)]
		public int PageSize {
			get {
				EnsureChildControls();
				return _gridView.PageSize;
			}
			set {
				EnsureChildControls();
				_gridView.PageSize = value;
			}
		}
		[DefaultValue(Effect.Normal)]
		public Effect DisplayEffect {
			get;
			set;
		}
		[DefaultValue(5)]
		public int TimeEffect {
			get;
			set;
		}
		[DefaultValue(1)]
		public int StepEffect {
			get;
			set;
		}
		protected internal const string ComboboxCss = "spExCombobox";
		protected internal const string InputImagePanelCss = "excbInputPanel";
		protected internal const string InputImagePanelDisableCss = "excbInputPanelDisable";
		protected internal const string InputPanelCss = "excbInput";
		protected internal const string ContextMenuCss = "excbContextMenu";
		private HtmlGenericControl _divCombobox;
		private HtmlGenericControl _divTextButtonBox;
		private HtmlGenericControl _divInput;
		private HtmlGenericControl _divContextMenu;
		private SpGridView _gridView;
		private TextBox _textCombobox;
		private HiddenField _hfValue;
		private System.Web.UI.WebControls.Image _image;
		private int _textColumnIndex = -1;
		private bool _hasDatabinding;
		protected override void CreateChildControls() {
			base.CreateChildControls(); _divCombobox = new HtmlGenericNaming("div");
			_divCombobox.Attributes["class"] = ComboboxCss;

			_divTextButtonBox = new HtmlGenericControl("div");
			_divTextButtonBox.Attributes["class"] = InputImagePanelCss;

			_divInput = new HtmlGenericControl("div");
			_divInput.Attributes["class"] = InputPanelCss;

			_divContextMenu = new HtmlGenericControl("div");
			_divContextMenu.Attributes["class"] = ContextMenuCss;
			_divContextMenu.Style.Add(HtmlTextWriterStyle.Visibility, "hidden");
			_gridView = new SpGridView();
			_gridView.ShowLoadingPanel = true;
			_gridView.EnableFilter = true;
			_gridView.EnableSort = true;
			_gridView.PreventUnSelectByClick = true;
			_gridView.RowCreated += (GridViewRowCreated);
			_gridView.BeforeDataBinding += (GridViewBeforeDataBinding);
			_divContextMenu.Controls.Add(_gridView);
			_textCombobox = new TransparentBgTextEdit();
			_textCombobox.AutoCompleteType = AutoCompleteType.None;

			_textCombobox.BackColor = Color.Transparent;
			_hfValue = new HiddenField();
			_divInput.Controls.Add(_textCombobox);
			_divInput.Controls.Add(_hfValue);

			_textCombobox.AutoCompleteType = AutoCompleteType.None;
			_image = new System.Web.UI.WebControls.Image {

				Width = new Unit(16),
				Height = new Unit(16),
				ImageUrl = "~/style/simple/images/navigate_close.png"
			};
			Controls.Add(_divCombobox);
			_divCombobox.Controls.Add(_divTextButtonBox);
			_divCombobox.Controls.Add(_divContextMenu);

			_divTextButtonBox.Controls.Add(_divInput);
			_divTextButtonBox.Controls.Add(_image);
		}
		public string NoItemDisplayText {
			get {
				EnsureChildControls();
				return _gridView.NoItemDisplayText;
			}
			set {
				EnsureChildControls();
				_gridView.NoItemDisplayText = value;
			}
		}
		public SimplePaging.SpPaging PagingControl {
			get {
				EnsureChildControls();
				return _gridView.PagingControl;
			}
		}
		void GridViewBeforeDataBinding(object sender, EventArgs e) {
			_hasDatabinding = true;
			FindTextColumnIndex();
		}

		private void FindTextColumnIndex() {
			if (!String.IsNullOrEmpty(TextField)) {
				for (int i = 0; i < _gridView.VisibleColumns.Count; i++) {
					var c = _gridView.VisibleColumns[i];
					if (c.FieldName == TextField) {
						_textColumnIndex = i;
						if (_gridView.HasChildGrid) _textColumnIndex++;
						break;
					}
				}
			}
		}

		void GridViewRowCreated(object sender, SpGvRowCreatedEventArgs e) {
			if (_textColumnIndex == -1) {
				if (!String.IsNullOrEmpty(TextField)) {
					e.Item.Attributes["_excbxtext_"] = String.Format("{0}", e.GetValue(TextField));
				}
			}
		}
		public override string ID {
			get {
				EnsureChildControls();
				return _divCombobox.ID;
			}
			set {
				EnsureChildControls();
				_divCombobox.ID = value;
				_gridView.ID = value + "Grid";
				_textCombobox.ID = value + "Txt";
				_divContextMenu.ID = value + "Menu";
				_divTextButtonBox.ID = value + "Panel";
				_hfValue.ID = value + "Value";
			}
		}

		public override string ClientID {
			get {
				EnsureChildControls();
				return _divCombobox.ClientID;
			}
		}
		[DefaultValue("")]
		public String Text {
			get {
				EnsureChildControls();
				return _textCombobox.Text;
			}
			set {
				EnsureChildControls();
				_textCombobox.Text = value;
			}
		}
		[DefaultValue("")]
		public string Value {
			get {
				EnsureChildControls();
				return _hfValue.Value;
			}
			set {
				EnsureChildControls();
				_hfValue.Value = value;
			}
		}
		[DefaultValue(SpShowKey.None)]
		public SpShowKey ShowKey { get; set; }
		[Description("")]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[MergableProperty(false)]
		[Category("Data")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[DefaultValue("")]
		public SpGvColumnCollection Columns {
			get {
				EnsureChildControls();
				return _gridView.Columns;
			}
		}

		public override void DataBind() {
			EnsureChildControls();
			_gridView.ClientScriptHandlerRowClick = ClientName + ".Call(7, this);";
			_gridView.DataBind();
		}
		protected override string StyleSheetFileName {
			get {
				return SpCombobox.CssFile;
			}
		}

		public override bool IsCallback {
			get {
				EnsureChildControls();
				return _gridView.IsCallback;
			}
		}
		[DefaultValue(MenuContainerMode.ButtonOnly)]
		public MenuContainerMode CloseMode { get; set; }
		public FilterDataCollection FilterDatas {
			get {
				EnsureChildControls();
				return _gridView.FilterDatas;
			}
		}
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);
			IncludeScriptOnLoad(SpCombobox.SpComboboxType, "Script", "Library.WebControls.SimpleCombobox.include.SpCombobox.js", UtilLib, EffectLib);
		}
		protected override void CreateClientObjectAtRender(HtmlTextWriter writer) {

			BeginScriptTag(writer);

			writer.Write("var {0}=new SpCombobox('{0}','{1}','{2}','{3}','{4}',{5},'{6}','{7}',{8},{9},'{10}','{11}',{12},{13},{14},{15},{16});",
				ClientName,
				_divContextMenu.ClientID,
				_textCombobox.ClientID,
				_hfValue.ClientID,
				_divTextButtonBox.ClientID,
				(Int32)SpComboboxFilterMode.None,
				HttpContext.Current.Server.HtmlEncode(_textCombobox.Text),
				_hfValue.Value,
				0,
				500,
				String.Empty,
				(Int32)DisplayEffect,
				TimeEffect,
				StepEffect,
				ClientEnable.ToString().ToLower(),
				Boolean.FalseString.ToLower(),
				(Int32)ShowKey);

			writer.Write(String.Format("{0}.InitEx({1},{2});", ClientName, _gridView.ClientName, _textColumnIndex));
			AddScriptHandler(writer, 1, ClientScript.SelectIndexChanged, "AddHandler");
			AddScriptHandler(writer, 2, ClientScript.Shown, "AddHandler");
			AddScriptHandler(writer, 3, ClientScript.Showing, "AddHandler");
			AddScriptHandler(writer, 4, ClientScript.BeforeCallback, "AddHandler");
			AddScriptHandler(writer, 5, ClientScript.TextChanged, "AddHandler");
			EndScriptTag(writer);

		}
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[MergableProperty(false)]
		[Category("Data")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[DefaultValue("")]
		public TextBox TextEdit {
			get {
				EnsureChildControls();
				return _textCombobox;
			}
		}
		protected override void Render(HtmlTextWriter writer) {
			if (!Visible) return;
			if (!_hasDatabinding) FindTextColumnIndex();
			if (!TextEdit.Enabled || TextEdit.ReadOnly) {
				TextEdit.Style.Add(HtmlTextWriterStyle.Cursor, "default");
			}
			if (!_image.Visible) {
				_textCombobox.Width = new Unit(_divContextMenu.Style[HtmlTextWriterStyle.Width]);
			}
			if (CloseMode == MenuContainerMode.ButtonOnly || CloseMode == MenuContainerMode.ButtonAndText)
				_image.Attributes["onclick"] = ClientName + ".Call(2)";
			_divCombobox.Attributes["onkeyup"] = "return " + ClientName + ".Call(3, event)";
			_divCombobox.Attributes["onkeydown"] = "return " + ClientName + ".Call(4, event)";
			_divCombobox.Attributes["onkeypress"] = "return " + ClientName + ".Call(5, event)";
			_textCombobox.Attributes["onchange"] = ClientName + ".Call(1)";
			if (CloseMode == MenuContainerMode.ButtonAndText)
				_textCombobox.Attributes["onclick"] = ClientName + ".Call(2)";
			_textCombobox.Attributes["autocomplete"] = "off";
			bool enableFitler = false;
			bool oldFilter = _gridView.EnableFilter;
			foreach (var column in _gridView.VisibleColumns) {
				if (column.Filter != FilterType.None) {
					enableFitler = true;
					break;
				}
			}

			_gridView.EnableFilter = enableFitler;
			base.Render(writer);

			_gridView.EnableFilter = oldFilter;
		}

		public event EventHandler PageIndexChanged {
			add {
				EnsureChildControls();
				_gridView.PageIndexChanged += value;
			}
			remove {
				EnsureChildControls();
				_gridView.PageIndexChanged -= value;
			}
		}

		public event CustomCallbackEventHandler CustomCallback {
			add {
				EnsureChildControls();
				_gridView.CustomCallback += value;
			}
			remove {
				EnsureChildControls();
				_gridView.CustomCallback -= value;
			}
		}

		public event EventHandler<SpGvRowCreatedEventArgs> RowCreated {
			add {
				EnsureChildControls();
				_gridView.RowCreated += value;
			}
			remove {
				EnsureChildControls();
				_gridView.RowCreated -= value;
			}
		}

		//public SpGridView InnerGrid() {
		//  return _gridView;
		//}



		public event EventHandler<SpGvCellCreatedEventArgs> CellCreated {
			add {
				EnsureChildControls();
				_gridView.CellCreated += value;
			}
			remove {
				EnsureChildControls();
				_gridView.CellCreated -= value;
			}
		}

		private class TransparentBgTextEdit : WebTextEdit {
			[DefaultValue(typeof(Color), "Transparent")]
			public override Color BackColor {
				get {
					return base.BackColor;
				}
				set {
					base.BackColor = value;
				}
			}
		}
	}
}
